#include "SQUA.h"

SQUA_T* SQUA_t;



//************************************
// Method:    	CALCU_SAMA						//< SAMA运算函数
// Programmer:  duan
// Time:		2018/03/19
// Returns:   	bool							//< 成功：true；失败：false
// Parameter: 	Model_Base_t * arg				//< 模块参数结构体指针
// Parameter: 	float dt						//< 运算周期
// Parameter: 	bool * DI						//< 数字量输入值数组指针
// Parameter: 	bool * DO						//< 数字量输出值数组指针
// Parameter: 	bool * AI						//< 模拟量输入值数组指针
// Parameter: 	bool * AO						//< 模拟量输出值数组指针
//************************************
bool CALCU_SAMA(SQUA)(Model_Base_t* arg, float dt, bool* DI, bool* DO, float* AI, float* AO)
{
	/****************变量定义区开始**************/
	/*<<<<<定义输入变量并初始化>>>>>*/
	bool Enable;

	/*<<<<<定义输出变量并初始化>>>>>*/
	float Output_Value;

	/*<<<<<定义参数变量并初始化>>>>>*/
	float High_Value;	         //< 方波波峰
	float Low_Value;	         //< 方波波谷
	float Time;			         //< 方波响应需等待的时间
	float Width_Value;           //< 方波宽度

	/*<<<<<定义中间变量>>>>>*/
	float* Time_Sum = NULL;		 //< 方波响应等待时间累积值
	float* Time_Last = NULL;     //< 记录上位上一次下发的“发生时间”
	float* Run_Time = NULL;      //<  方波模块运行时间
	 
	/****************变量定义区结束**************/

	NAME(SQUA)* Obj = (NAME(SQUA)*)arg;

	/****************变量赋值**************/
	/*<<<<<输入变量赋值>>>>>*/
	 Enable = DI[0];

	/*<<<<<参数变量赋值>>>>>*/
	 High_Value = Obj->Par.High_Value;	
	 Low_Value = Obj->Par.Low_Value;	
     Time = Obj->Par.Time;			
	 Width_Value = Obj->Par.Width_Value;  

	/*<<<<<中间变量赋值>>>>>*/
	  Time_Sum = &(Obj->Sta.Time_Sum);
	  Time_Last = &(Obj->Sta.Time_Last);   
	  Run_Time = &(Obj->Sta.Run_Time);

	/**************变量赋值结束************/

	/********************************************/
	/**************算法功能实现开始**************/
	/********************************************/
	  if (Time_Last[0] != Time)
	  {
		  Output_Value = 0;
		  Time_Sum[0] = 0;
		  Run_Time[0] = 0;
		  Time_Last[0] = Time;
	  }

	  if (Low_Value > High_Value || Width_Value <= 0)
		  return false;

	  if (Enable == false)           
	  {
		  Output_Value = 0;
		  Time_Sum[0] = 0;
		  Run_Time[0] = 0;
	  }
	  else                          
	  {
		  if (Time_Sum[0] >= Time)  
		  {
			  Time_Sum[0] = Time;

			  if (Run_Time[0] >= 2 * Width_Value)                                //< 周期
				  Run_Time[0] = 0;
			  if (Run_Time[0] >= 0 && Run_Time[0] < Width_Value)                 //< 前半个周期输出波峰
				  Output_Value = High_Value;
			  if (Run_Time[0] >= Width_Value && Run_Time[0] < 2.0*Width_Value)   //< 后半个周期输出波谷
				  Output_Value = Low_Value;
			  
			  Run_Time[0] += dt;  
		  }
		  else
		  { 
			  Time_Sum[0] = Time_Sum[0] + dt;
			  Output_Value = 0;
		  }
	  }
	  
	//**************算法功能实现结束**************/
	/********************************************/

	/****************运算结果输出**************/
	  AO[0] = Output_Value;
	/**************运算结果输出完毕************/

	  //if (arg->List_Base.ID==575) {
		 // printf("Value is %f!!!\n", AO[0]);
	  //}
	 return true;
}

//************************************
// Method:    	BCPARA							//< 广播SAMA参数变量函数（无参数需要广播的模块直接将BCPara函数设置为NULL即可）
// Programmer:  duan
// Time:		2019/03/19
// Returns:   	int								//< 成功：返回打包字节个数；失败：返回0
// Parameter: 	Model_Base_t * arg				//< 模块参数结构体指针
// Parameter: 	void ** Data					//< 广播SAMA参数的数据包的指针
//************************************
int BC_PARA(SQUA)(Model_Base_t* arg, void** Data)
{
	NAME(SQUA)* Obj = (NAME(SQUA)*)arg;
	BC_PARA_PUBLIC(Obj);
	return 0;
}

//************************************
// Method:    	BAK_STA							//< 备份SAMA运算中间参数
// Programmer:  duan
// Time:		2019/03/19
// Returns:   	int								//< 成功：返回打包字节个数；失败：返回0
// Parameter: 	Model_Base_t * arg				//< 指定模块类型链表的指针
// Parameter: 	void ** Data					//< 存放数据包当前指针位置的地址
//************************************
int BAK_STA(SQUA)(Model_Base_t* arg, void** Data)
{
	NAME(SQUA)* Obj = (NAME(SQUA)*)arg;
	BAK_STA_PRIVATE(Obj);
	return 0;
}



//************************************
// Method:    	ANA_STA							//< 解析备份的SAMA运算中间参数
// Programmer:  duan
// Time:		2019/03/19
// Returns:   	int								//< 成功：返回解析字节个数；失败：返回0
// Parameter: 	Model_Base_t * arg				//< 模块参数结构体指针
// Parameter: 	void ** Data					//< 存放数据包当前指针位置的地址
//************************************
int ANA_STA(SQUA)(Model_Base_t* arg, void** Data)
{
	NAME(SQUA)* Obj = (NAME(SQUA)*)arg;
	ANA_STA_PRIVATE(Obj);
	return 0;
}



//************************************
// Method:    	CHANGE_PAR				//< 在线修改模块参数函数
// Programmer:  duan
// Time:		2019/03/19
// Returns:   	int						//< 读取字节长度计数值
// Parameter: 	Model_Base_t* arg		//< 指定模块类型链表的指针
// Parameter: 	void** Data				//< 存放数据包当前指针位置的地址
//************************************
int CHANGE_PAR(SQUA)(Model_Base_t* arg, void** Data)
{
	int _iLen = 0;
	MEMREAD(((NAME(SQUA)*)arg)->Par, Data[0]);
	return _iLen;
}



//************************************
// Method:    	INIT_STAPAR						//< 初始化模块运算中间参数
// Programmer:  duan
// Time:		2019/03/19
// Parameter: 	Model_Base_t* arg				//< 模块参数结构体指针
//************************************
void INIT_STAPAR(SQUA)(Model_Base_t* arg)
{
	NAME(SQUA)* name = (NAME(SQUA)*)arg;
	/****************初始化中间变量结构体**************/
	memset(&(name->Sta), 0, sizeof(name->Sta));
	/**************初始化中间变量结构体结束************/
	
	/****************对中间变量结构体的相关参数进行赋值**************/
	name->Sta.Time_Last = name->Par.Time;
	/**************对中间变量结构体的相关参数进行赋值结束************/
}
